/*
 * Helstius--Basic chemistry application
 * This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 * Copyright 2012 Jaked122
 */
package org.helstius.chem;

import java.util.HashMap;
import java.util.TreeMap;
import java.util.TreeSet;

import org.helstius.util.Utility;

public class ChemicalEquation {
	public ChemicalEquation(String o) {
		originalequation = o;
		g = new Parser();
		ElementCounts = g.getcounts(originalequation);
	}

	public void setOriginalString(String o) {
		originalequation = o;
		ElementCounts = g.getcounts(originalequation);
	}

	public String getOriginalString() {
		return originalequation;
	}

	/**
	 * Says whether or not the coefficient has been assigned to since the map
	 * has been calculated.
	 */
	boolean coefficientchanged = false;
	/**
	 * The integer which multiplies the number of elements in the equation.
	 */
	int coefficient = 1;
	Parser g;

	public void setCoefficient(int coef) {
		// if the new coefficient is the same as the old one, it would be a
		// waste of time to designate that it calculate the map again.
		if (coef != coefficient) {
			coefficientchanged = true;
			coefficient = coef;
		}

	}

	public float getWeight() {
		float w = g.parsechem(originalequation);
		return w;
	}

	public int getCoefficient() {
		return coefficient;
	}

	/**
	 * Get the number of elements at the given coefficient
	 * 
	 * @param atcoef
	 *            the coefficient
	 * @return the map containing the matched pairs of elements.
	 */
	public HashMap<String, Integer> getElementCounts(int atcoef) {
		setCoefficient(atcoef);
		return getElementCounts();
	}

	public ChemicalEquation(HashMap<String, Integer> h) {
		String f = "";
		for (String e : h.keySet()) {
			f += e + Integer.toString(h.get(e));
		}
		originalequation = f;
		ElementCounts = h;

	}

	public ChemicalEquation getEmpiricalEquation() {
		ChemicalEquation r;
		int divisor = Utility.GCD(ElementCounts.values());
		HashMap<String, Integer> g = new HashMap<String, Integer>();
		for (String e : ElementCounts.keySet()) {
			g.put(e, ElementCounts.get(e) / divisor);
		}
		r = new ChemicalEquation(g);
		return r;
	}

	public ChemicalEquation GetOriginal(ChemicalEquation emp, float molar) {
		int mult = (int) Math.floor((double) molar
				/ Math.floor(emp.getWeight()));
		HashMap<String, Integer> e = new HashMap<String, Integer>();
		for (String i : emp.ElementCounts.keySet())
			e.put(i, (int) mult * emp.ElementCounts.get(i));
		return new ChemicalEquation(e);

	}

	public String toString() {
		return originalequation;
	}

	public HashMap<String, Integer> getElementCounts() {
		if (coefficientchanged) {
			Parser.multiplyMaps(ElementCounts, coefficient, LastComputedResult);
			coefficientchanged = false;
		}
		return LastComputedResult;
	}

	String originalequation;
	/**
	 * Original element count.
	 */
	HashMap<String, Integer> ElementCounts;
	/**
	 * The cached version, for actually using stuff.
	 */
	HashMap<String, Integer> LastComputedResult;
}
